package com.zrrd.yunchmall.study.redis;

import com.zrrd.yunchmall.Department;
import com.zrrd.yunchmall.RedisApp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;
import java.util.concurrent.TimeUnit;

@SpringBootTest(classes = RedisApp.class)
@RunWith(SpringRunner.class)
public class RedisTest2 {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Test
    public void t1() {
        // 用于操作字符串类型
        ValueOperations valueOperations = redisTemplate.opsForValue();
        ListOperations listOperations = redisTemplate.opsForList();
        SetOperations setOperations = redisTemplate.opsForSet();
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        HashOperations hashOperations = redisTemplate.opsForHash();
    }
    //如果需要操作字符串类型，那么就选择 ValueOperations
    @Test
    public void t2() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("author", "李野");
        System.out.println("OK.");
    }
    //如何将一个实体类对象信息，保存到Redis中存储
    @Test
    public void t3() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
//        Department department = new Department(1, "行政部", "北京");
        Department department = new Department(2, "研发部", "上海");
//        valueOperations.set("dept01", department);
        // 这个key将会在1分钟后过期
        valueOperations.set("dept" + 2, department, 10, TimeUnit.MINUTES);
        System.out.println("OK");
    }
    //将t3保存的部门信息查询到程序中
    @Test
    public void t4() {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Department department = (Department) valueOperations.get("dept01");
        System.out.println(department);
        System.out.println("OK");
    }
    //将多个部门对象同时保存在一个key当中
    @Test
    public void t5() {
        ListOperations listOperations = redisTemplate.opsForList();
        List<Department> departmentList = new LinkedList<>();
        departmentList.add(new Department(1, "行政部", "北京"));
        departmentList.add(new Department(2, "研发部", "哈尔滨"));
        departmentList.add(new Department(3, "财务部", "上海"));
        departmentList.add(new Department(4, "市场部", "合肥"));
        //一次将整个集合push到redis的list类型key当中
        listOperations.rightPushAll("allDeptList", departmentList);
        System.out.println("OK");
    }
    //一次将整个List查询到程序中
    @Test
    public void t6() {
        ListOperations listOperations = redisTemplate.opsForList();
        List<Department> departmentList = listOperations.range("allDeptList", 0, -1);
        departmentList.forEach(dept -> System.out.println(dept));
        System.out.println("------------------------------------");
        //查找指定下标的对象
        Department department = (Department) listOperations.index("allDeptList", 1);
        System.out.println("第1个位置的部门是：" + department);
        System.out.println("OK");
    }

    // set类型的使用
    @Test
    public void t7() {
        SetOperations setOperations = redisTemplate.opsForSet();
        setOperations.add("fruitSet1", "苹果", "草莓", "橙子", "芒果");
        setOperations.add("fruitSet2", "苹果", "西瓜", "香蕉", "葡萄", "车厘子");
        System.out.println("OK");
    }

    @Test
    public void t8() {
        SetOperations setOperations = redisTemplate.opsForSet();
        long count = setOperations.size("fruitSet1");
        System.out.println("水果集1当中有" + count + "种水果");
        System.out.println("分别是：");
        Set<String> fruitSet1 = setOperations.members("fruitSet1");
        fruitSet1.forEach(item -> System.out.println(item));

        long count2 = setOperations.size("fruitSet2");
        System.out.println("水果集2当中有" + count2 + "种水果");

        Set<String> interSet = setOperations.intersect("fruitSet1", "fruitSet2");
        System.out.println("两个水果集的交集有：");
        interSet.forEach(item -> System.out.println(item));

        Set<String> unionSet = setOperations.union("fruitSet1", "fruitSet2");
        System.out.println("两个水果集的并集有：");
        unionSet.forEach(item -> System.out.println(item));

        Set<String> diffSet = setOperations.difference("fruitSet1", "fruitSet2");
        System.out.println("两个水果集的差集有：");
        diffSet.forEach(item -> System.out.println(item));
    }
    @Test
    public void t9() {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("vegetableSet", "芥蓝", 7);
        zSetOperations.add("vegetableSet", "小红萝卜", 2.45);
        zSetOperations.add("vegetableSet", "青萝卜", 1.67);
        zSetOperations.add("vegetableSet", "大白菜", 0.98);
        zSetOperations.add("vegetableSet", "圆葱", 2.97);
        zSetOperations.add("vegetableSet", "油菜", 5.27);
        zSetOperations.add("vegetableSet", "平菇", 7.21);
        System.out.println("OK");
    }
    @Test
    public void t10() {
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("vegetableSet", "平菇", 8.21);
        //score的值在原有基础上加上多少
        zSetOperations.incrementScore("vegetableSet", "大白菜", 0.1);
        //score的值在原有基础上减去多少
        zSetOperations.incrementScore("vegetableSet", "小红萝卜", -0.2);
        System.out.println("----------------------------------");
        //只差value，不看score
//        Set<ZSetOperations.TypedTuple> tupleSet = zSetOperations.range("vegetableSet", 0, -1);
        //既查询value，也查询score
//        Set<ZSetOperations.TypedTuple> tupleSet = zSetOperations.rangeByScoreWithScores("vegetableSet", 0.0, 200);
        //按照score降序查询
        Set<ZSetOperations.TypedTuple> tupleSet
                = zSetOperations.reverseRangeByScoreWithScores("vegetableSet", 0.0, 200);
        System.out.println(tupleSet);
        tupleSet.forEach(tuple -> {
            System.out.println(tuple.getValue() + ": " + tuple.getScore());
        });
        System.out.println("----------------------------------");
    }

    @Test
    public void t11() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put("deptMap", "deptno", "1");
        hashOperations.put("deptMap", "dname", "技术部");
        hashOperations.put("deptMap", "loc", "哈尔滨");
        System.out.println("OK");
    }

    @Test
    public void t12() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        Map map = new HashMap();
        map.put("deptno", "2");
        map.put("dname", "行政部");
        map.put("loc", "北京");
        hashOperations.putAll("deptMap2", map);
        System.out.println("OK");
    }

    @Test
    public void t13() {
        HashOperations hashOperations = redisTemplate.opsForHash();
        long size = hashOperations.size("deptMap2");
        if (hashOperations.hasKey("deptMap2", "dname")) {
            System.out.println("有部门名称");
        }
        if (hashOperations.hasKey("deptMap2", "manager")) {
            System.out.println("部门经理：" + hashOperations.get("deptMap2", "manager"));
        } else {
            System.out.println("该部门未设置经理");
        }
        Map deptInfo = hashOperations.entries("deptMap2");
        System.out.println(deptInfo);
    }


    @Test
    public void test14() {
        boolean hasKey = redisTemplate.hasKey("LOGIN_TOKEN_QWlGJtjZ2oWulBb1pNZuue1xwqOYYBO19-YmHW2FGgw");
        System.out.println(hasKey);
    }

}
